package com.weijian.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weijian.common.BaseContext;
import com.weijian.common.exception.ErrorCode;
import com.weijian.common.exception.ServiceException;
import com.weijian.dal.entity.User;
import com.weijian.dal.vo.UserVO;
import com.weijian.mapper.UserMapper;
import com.weijian.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    /**
     * 用户注册
     */
    @Override
    public long userRegister(String userAccount, String userPassword) {
        // 1. 校验
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new ServiceException(new ErrorCode(401, "不能为空"));
        }
        if (userAccount.length() < 4) {
            throw new ServiceException(new ErrorCode(401, "用户账号过短"));
        }
        if (userPassword.length() < 8) {
            throw new ServiceException(new ErrorCode(401, "用户密码过短"));
        }
        synchronized (userAccount.intern()) {
            // 账户不能重复
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(User::getUserAccount, userAccount);
            long count = 0;
            try {
                count = baseMapper.selectCount(lambdaQueryWrapper);
            } catch (Exception e) {
                log.error("数据库异常", e);
                throw new RuntimeException(e);
            }
            if (count > 0) {
                throw new ServiceException(new ErrorCode(401, "账号重复"));
            }
            // 3. 插入数据
            User user = new User();
            user.setUserAccount(userAccount);
            user.setUserPassword(userPassword);
            save(user);
            return user.getId();
        }
    }

    /**
     * 用户登录
     */
    @Override
    public UserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {
        // 1. 校验
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new ServiceException(new ErrorCode(401, "参数为空"));
        }
        if (userAccount.length() < 4) {
            throw new ServiceException(new ErrorCode(401, "账号错误"));
        }
        if (userPassword.length() < 8) {
            throw new ServiceException(new ErrorCode(401, "密码错误"));
        }
        // 查询用户是否存在
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserAccount, userAccount).eq(User::getUserPassword, userPassword);
        User user = baseMapper.selectOne(lambdaQueryWrapper);
        log.info(String.valueOf(user.getId()));
        // 用户不存在
        if (user == null) {
            throw new ServiceException(new ErrorCode(401, "用户不存在或密码错误"));
        }
        Map<String, Object> map = new HashMap<>() {
            private static final long serialVersionUID = 1L;

            {
                put("user_id", user.getId());
                put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60);
            }
        };
        String token = JWTUtil.createToken(map, "weijian".getBytes());
        UserVO userVO = getUserVO(user);
        userVO.setToken(token);
        return userVO;
    }

    public UserVO getUserVO(User user) {
        if (user == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    public List<UserVO> getUserVO(List<User> userList) {
        if (CollUtil.isEmpty(userList)) {
            return new ArrayList<>();
        }
        return userList.stream().map(this::getUserVO).collect(Collectors.toList());
    }

    /**
     * 扣减余额
     */
    @Override
    public void deductMoney(String pw, Integer totalFee) {
        User user = getById(BaseContext.getCurrentId());
        if (user == null || !user.getUserPassword().equals(pw)) {
            throw new ServiceException(new ErrorCode(401, "密码错误"));
        }
        if (user.getBalance() < totalFee) {
            throw new ServiceException(new ErrorCode(401, "余额不足"));
        }
        user.setBalance(user.getBalance() - totalFee);
    }
}




